﻿
using System;
using System.Xml;

namespace Xacml.Core
{
  public abstract class XacmlElement
  {
    private XacmlVersion _schemaVersion;
    private XacmlSchema _schema;

    public XacmlVersion SchemaVersion
    {
      get
      {
        return this._schemaVersion;
      }
    }

    public XacmlSchema Schema
    {
      get
      {
        return this._schema;
      }
    }

    public abstract bool IsReadOnly { get; }

    protected internal string XmlDocumentSchema
    {
      get
      {
        if (this._schema == XacmlSchema.Context)
        {
          if (this.SchemaVersion == XacmlVersion.Version10 || this.SchemaVersion == XacmlVersion.Version11)
            return "urn:oasis:names:tc:xacml:1.0:context";
          if (this.SchemaVersion == XacmlVersion.Version20)
            return "urn:oasis:names:tc:xacml:2.0:context";
        }
        else if (this._schema == XacmlSchema.Policy)
        {
          if (this.SchemaVersion == XacmlVersion.Version10 || this.SchemaVersion == XacmlVersion.Version11)
            return "urn:oasis:names:tc:xacml:1.0:policy";
          if (this.SchemaVersion == XacmlVersion.Version20)
            return "urn:oasis:names:tc:xacml:2.0:policy";
        }
        throw new ApplicationException("invalid schema and version information.");
      }
    }

    protected XacmlElement(XacmlSchema schema, XacmlVersion schemaVersion)
    {
      this._schema = schema;
      this._schemaVersion = schemaVersion;
    }

    protected XacmlElement()
    {
    }

    protected bool ValidateSchema(XmlReader reader, XacmlVersion version)
    {
      if (this._schema == XacmlSchema.Policy)
      {
        if (version == XacmlVersion.Version11 || version == XacmlVersion.Version10)
          return reader.NamespaceURI == "urn:oasis:names:tc:xacml:1.0:policy";
        if (version == XacmlVersion.Version20)
          return reader.NamespaceURI == "urn:oasis:names:tc:xacml:2.0:policy";
      }
      else
      {
        if (version == XacmlVersion.Version11 || version == XacmlVersion.Version10)
          return reader.NamespaceURI == "urn:oasis:names:tc:xacml:1.0:context";
        if (version == XacmlVersion.Version20)
          return reader.NamespaceURI == "urn:oasis:names:tc:xacml:2.0:context";
      }
      throw new Exception("Invalid version provided");
    }
  }
}
